package com.fancy.music.util;

import com.fancy.music.config.FileUploadConfig;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.UUID;

@Slf4j
@Component
@RequiredArgsConstructor
public class FileUploadUtil {

    private final FileUploadConfig fileUploadConfig;

    /**
     * 上传音频文件
     */
    public String uploadAudioFile(MultipartFile file) throws IOException {
        return uploadFile(file, fileUploadConfig.getAudioPath(), fileUploadConfig.getAudioFormats());
    }

    /**
     * 上传封面图片
     */
    public String uploadCoverImage(MultipartFile file) throws IOException {
        return uploadFile(file, fileUploadConfig.getCoverPath(), fileUploadConfig.getImageFormats());
    }

    /**
     * 上传歌词文件
     */
    public String uploadLyricFile(MultipartFile file) throws IOException {
        return uploadFile(file, fileUploadConfig.getLyricPath(), fileUploadConfig.getLyricFormats());
    }

    /**
     * 通用文件上传方法
     */
    private String uploadFile(MultipartFile file, String subPath, String allowedFormats) throws IOException {
        if (file == null || file.isEmpty()) {
            throw new IllegalArgumentException("文件不能为空");
        }

        // 检查文件格式
        String originalFilename = file.getOriginalFilename();
        if (originalFilename == null) {
            throw new IllegalArgumentException("文件名不能为空");
        }

        String fileExtension = getFileExtension(originalFilename);
        if (!isAllowedFormat(fileExtension, allowedFormats)) {
            throw new IllegalArgumentException("不支持的文件格式: " + fileExtension);
        }

        // 创建目录
        String fullPath = fileUploadConfig.getBasePath() + subPath;
        Path uploadPath = Paths.get(fullPath);
        if (!Files.exists(uploadPath)) {
            Files.createDirectories(uploadPath);
        }

        // 生成唯一文件名
        String fileName = generateUniqueFileName(originalFilename);
        Path filePath = uploadPath.resolve(fileName);

        // 保存文件
        file.transferTo(filePath.toFile());

        // 返回相对路径
        String relativePath = subPath + fileName;
        log.info("文件上传成功: {}", relativePath);

        return relativePath;
    }

    /**
     * 获取文件扩展名
     */
    private String getFileExtension(String filename) {
        int lastDotIndex = filename.lastIndexOf('.');
        if (lastDotIndex == -1) {
            return "";
        }
        return filename.substring(lastDotIndex + 1).toLowerCase();
    }

    /**
     * 检查文件格式是否允许
     */
    private boolean isAllowedFormat(String fileExtension, String allowedFormats) {
        String[] formats = allowedFormats.split(",");
        return Arrays.asList(formats).contains(fileExtension.toLowerCase());
    }

    /**
     * 生成唯一文件名
     */
    private String generateUniqueFileName(String originalFilename) {
        String fileExtension = getFileExtension(originalFilename);
        String uuid = UUID.randomUUID().toString().replace("-", "");
        return uuid + "." + fileExtension;
    }

    /**
     * 删除文件
     */
    public boolean deleteFile(String relativePath) {
        try {
            if (relativePath == null || relativePath.isEmpty()) {
                return false;
            }

            Path filePath = Paths.get(fileUploadConfig.getBasePath() + relativePath);
            if (Files.exists(filePath)) {
                Files.delete(filePath);
                log.info("文件删除成功: {}", relativePath);
                return true;
            }
            return false;
        } catch (IOException e) {
            log.error("删除文件失败: {}", relativePath, e);
            return false;
        }
    }

    /**
     * 获取文件大小（字节）
     */
    public long getFileSize(MultipartFile file) {
        return file.getSize();
    }

    /**
     * 检查文件大小是否超过限制（MB）
     */
    public boolean isFileSizeValid(MultipartFile file, long maxSizeMB) {
        long maxSizeBytes = maxSizeMB * 1024 * 1024;
        return file.getSize() <= maxSizeBytes;
    }
}
